package com.kobeliu.api.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * rabbitMQ工具类
 */
@Configuration
@Slf4j
public class DelayIndustryConfig {

    //定义交换机名称
    public static final String EXCHANGE_DELAY_REFRESH = "exchange_delay_refresh";
    public static final String QUEUE_DELAY_REFRESH = "queue_delay_refresh";

    //定义固定的routingKey
    public static final String DELAY_REFRESH_INDUSTRY = "delay.refresh.industry";

    //创建交换机
    @Bean(EXCHANGE_DELAY_REFRESH)
    public Exchange exchange(){
        return ExchangeBuilder.
                topicExchange(EXCHANGE_DELAY_REFRESH)
                .durable(true)
                .delayed()
                .build();
    }

    //创建队列
    @Bean(QUEUE_DELAY_REFRESH)
    public Queue queue(){
        return QueueBuilder
                .durable(QUEUE_DELAY_REFRESH)
                .build();
    }

    //创建绑定关系
    @Bean
    public Binding delayBinding(@Qualifier(EXCHANGE_DELAY_REFRESH) Exchange exchange, @Qualifier(QUEUE_DELAY_REFRESH) Queue queue){
        return BindingBuilder.bind(queue)
                            .to(exchange)
                            .with("delay.refresh.*")
                            .noargs();
    }

    /**
     * 设置延迟的时间 单位毫秒
     * @param delayTimes
     * @return
     */
    public static MessagePostProcessor setDelayTimes(Integer delayTimes){

        return new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //设置延迟的时间，单位毫秒
                message.getMessageProperties().setDelay(delayTimes);
                //设置持久属性
                message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                return message;
            }
        };
    }

    @Bean
    public RabbitTemplate.ConfirmCallback delayConfirmCallback() {
        RabbitTemplate.ConfirmCallback delayConfirmCallback = new RabbitTemplate.ConfirmCallback() {
            /**
             * 回调函数
             *
             * @param correlationData 传入的数据
             * @param ack             true为成功 false为失败
             * @param msg             若成功，传回null,若失败，传回原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String msg) {

                log.info("传入交换机的消息为:{}", correlationData);
                log.info("传入是否成功:{}", ack);
                log.info("若传入失败，原因是:{}", msg);

            }

        };
        return delayConfirmCallback;
    }

}
